/****************************************************************************
**
** Copyright (C) 2009 by user *
** user@greenphonesdk *
**
** Contact: Qt Extended Information (info@qtextended.org)
**
** This file may be used under the terms of the GNU General Public License
** version 2.0 as published by the Free Software Foundation and appearing
** in the file LICENSE.GPL included in the packaging of this file.
**
** Please review the following information to ensure GNU General Public
** Licensing requirements will be met:
**     http://www.fsf.org/licensing/licenses/info/GPLv2.html.
**
****************************************************************************/

#include "neophonebook.h"


NeoPhoneBook::NeoPhoneBook(QString dir)
{
	fileName = "phonebook";
	home = dir;
    // Use this path for QVFB
    //fileName = "/home/user/Documents/phonebook";
    
    // Use this path for NEO 
    //fileName = "/home/root/Documents/phonebook";
}

NeoPhoneBook::~NeoPhoneBook()
{
    // Do nothing for now
}

/**
 * Add the entry to the phonebook using findIndex and save.
 */
int NeoPhoneBook::addEntry(NeoPhoneBookEntry *newEntry)
{   	
	return addEntry(newEntry, true);
}

int NeoPhoneBook::addEntry(NeoPhoneBookEntry *newEntry, bool save)
{    
	int index = findIndex(newEntry);
	phoneList.insert(index, newEntry);
	if (save) {
		savePhoneBook();
	}
	return index;
}

/**
 * Find the best index to insert into the list using binary search.
 */
int NeoPhoneBook::findIndex(NeoPhoneBookEntry *entry)
{
	return bSearch(entry->getContactName(), 0, phoneList.size());	
}

/**
 * Load the phonebook by reading the "phonebook" file and populating
 * phoneList.
 * @Ensure the content of phonebook is aloways corrent.
 * @Ensure each entry always has three | seperators.
 */
void NeoPhoneBook::loadPhoneBook()
{
	QDir dir = QDir::home();
	dir.cd(home);
	QFile file(dir.filePath(fileName));
	if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
	    qDebug() << "Can't open file" << fileName;
	    return;
	}
	
	QTextStream input(&file);
	int count = 0;
	while(!input.atEnd()) {
		count++;
	    QString line = input.readLine();
	    QStringList contactFields = line.split("|");
		if (contactFields.size() != 9) {
			qDebug() << "Invalid phonebook entry at line" << count;
			qDebug() << line;
			continue;
		}
	    NeoPhoneBookEntry *entry = 
				new NeoPhoneBookEntry(contactFields[0], contactFields[1]);
    	entry->setContactEmail(contactFields[2]);
		entry->setPictureFilePath(contactFields[3]);
		if (contactFields[4].isEmpty()) { 
			entry->setRingToneFilePath("Default");
		} else {
			entry->setRingToneFilePath(contactFields[4]);
		}
		if (contactFields[5].isEmpty()) { 
			entry->setVibrationPatternFilePath("Pulse");
		} else {
			entry->setVibrationPatternFilePath(contactFields[5]);
		}
		if (contactFields[6].isEmpty()) {
			entry->setLedPatternFilePath("Pulse");
		} else {
			entry->setLedPatternFilePath(contactFields[6]);
		}		
		if (contactFields[7].isEmpty()) {
			entry->setRingOption(0);
		} else {
			int option = contactFields[7].toInt();
			if (option != 0 && option != 1) {
				option = 0;
			}
			entry->setRingOption(option);
		}
		if (contactFields[8].isEmpty()) {
			entry->setRingOffset(0);
		} else {
			int offset = contactFields[8].toInt();
			if (offset < 0) offset = 0;
			entry->setRingOffset(offset);
		}	
			
		//qDebug() << "Adding contact" << entry->getContactName();
		addEntry(entry, false);	
	}
	file.close();
	savePhoneBook();
}

/**
 * Save the phonebook by writing phoneList to the "phonebook" file.
 */
void NeoPhoneBook::savePhoneBook()
{
    QDir dir = QDir::home();
	dir.cd(home);
	QFile file(dir.filePath(fileName));
	if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
	    qDebug() << "Can't open file" << fileName;
	    return;
	}
	QTextStream output(&file);
	for (int i=0; i<phoneList.size(); i++) {
		NeoPhoneBookEntry *entry = getElementAt(i);
		output << entry->getContactName() << "|" << 
				entry->getPhoneNumber() << "|" <<
				entry->getContactEmail() << "|" <<
				entry->getPictureFilePath() << "|" <<
				entry->getRingToneFilePath() << "|" <<
				entry->getVibrationPatternFilePath() << "|" <<
				entry->getLedPatternFilePath() << "|" <<
				QString::number(entry->getRingOption()) << "|" <<
				QString::number(entry->getRingOffset()) << endl;
	}
	output.flush();
	file.close();
}

/**
 * Remove all entries from the phoneList
 */
void NeoPhoneBook::clearPhoneBook()
{    
	phoneList.clear();
	savePhoneBook();
}

/**
 * Replace an entry in the phoneList at index with newEntry.
 */
int NeoPhoneBook::replaceEntry(int index, NeoPhoneBookEntry *newEntry)
{    
	deleteEntry(index);
	int newIndex = addEntry(newEntry);
	savePhoneBook();
	return newIndex;
}

/**
 * Remove an entry in the phoneList at index
 */
void NeoPhoneBook::deleteEntry(int index)
{
	if (index >= 0 && index <= phoneList.size()-1) {
		phoneList.removeAt(index);
	} else {
		qDebug() << "Can't delete entry at" << index << "(Invalid index)";
		return;
	}
	savePhoneBook();
}

/**
 * Return the size of the phoneList
 */
int NeoPhoneBook::getNumEntries()
{
	return phoneList.size();
}

/**
 * Return the element of phoneList at index.
 * Return Return NeoPhoneBookEntry* if exists, otherwise return 0;
 */
NeoPhoneBookEntry* NeoPhoneBook::getElementAt(int index)
{
    if (index >= 0 && index <= phoneList.size()-1) {
		return phoneList.at(index);
	} else {
		qDebug() << "Can't get entry at" << index << "(Invalid index)";
	}
	return 0;
}



int NeoPhoneBook::searchContact(QString name)
{
	return bSearch(name, 0, phoneList.size()-1);
}

int NeoPhoneBook::bSearch(QString name, int left, int right)
{	
	if (left > right) return -1;
	if (left == right) return left;
	int middle = (left+right)/2;
//qDebug()<<"search from"<<left<<"to"<<right<<"["<<middle<<"/"<<phoneList.size()<<"]";
	int diff = (phoneList.at(middle)->getContactName()).compare(name,
					 Qt::CaseInsensitive);
	if (diff == 0) return middle;
	if (diff > 0) return bSearch(name, left, middle);
	return bSearch(name, middle+1, right);
}


